﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Hyt.Core;
using System.Linq.Expressions;
using Hyt.Core.Interceptors;
using Hyt.Core.Security;
using Hyt.Core.Data;
using Hyt.Passport.QueryModels;
using Hyt.Passport.Models;
using Hyt.Passport.Repositories;

namespace Hyt.Passport.Service
{
    public class AdministratorService 
    {
        public IAdministratorRepository Repository { get; set; }
        public DepartmentService DepartmentService { get; set; }

        public virtual Administrator Login(string username, string password, string loginip)
        {
            var administrator = GetAll().FirstOrDefault(t => t.UserName == username);
            if (administrator==null)
            {
                Guard.Throw("用户名或密码错误");
            }
            if (administrator.Password.ToLower() != Hyt.Core.Cryptography.MD5.Encrypt(password.Trim().ToLower()).ToLower())
            {
                Guard.Throw("用户名或密码错误");
            }
            if (administrator.State == PassportStatus.Disabled)
            {
                Guard.Throw("你的帐号已被冻结");
            }
            administrator.LastLoginIp = administrator.ThisLoginIp;
            administrator.LastLoginDateTime = administrator.ThisLoginDateTime;
            administrator.ThisLoginDateTime = DateTime.Now;
            administrator.ThisLoginIp = loginip;
            administrator.LoginTimes += 1;
            Repository.UpdateAdministrator(administrator);
            return administrator;
        }

        public virtual void ModifyPassword(Administrator model)
        {
            Guard.CheckArg(model, "model");
            Guard.Check(model).PleaseInput(t => t.Password);
            if (model.Password.Trim().Length < 6)
            {
                Guard.Throw("密码必须大于6位");
            }
            var dbmodel = Get(model.Id);
            Guard.MustExist(dbmodel, "用户");
            if (model.Password == dbmodel.Password) return;
            dbmodel.Password = Hyt.Core.Cryptography.MD5.Encrypt(model.Password.Trim().ToLower()).ToLower();
            Repository.UpdateAdministrator(dbmodel); 
        }

        public virtual void ModifyPosition(Administrator model)
        {
            Guard.CheckArg(model, "model");
            var dbmodel = Get(model.Id);
            Guard.MustExist(dbmodel, "用户");
            if (model.PositionId == dbmodel.PositionId) return;
            dbmodel.PositionId = model.PositionId;
            Repository.UpdateAdministrator(dbmodel); 
        }

        public virtual void ModifyDepartment(Administrator model)
        {
            Guard.CheckArg(model, "model");
            var dbmodel = Get(model.Id);
            Guard.MustExist(dbmodel, "用户");
            if (model.DepartmentId == dbmodel.DepartmentId) return;
            dbmodel.DepartmentId = model.DepartmentId;
            Repository.UpdateAdministrator(dbmodel); 
        }

        public virtual void ModifyProfile(Administrator model)
        {
            Guard.CheckArg(model, "model");
            var dbmodel = Get(model.Id);
            Guard.MustExist(dbmodel, "用户");
            Guard.Check(model).PleaseInput(t => t.Name);
            dbmodel.Name = model.Name;
            Repository.UpdateAdministrator(dbmodel); 
        }

        public virtual Administrator Create(Administrator model)
        {
            Guard.CheckArg(model, "model");
            Guard.Check(model).PleaseInput(t => t.UserName,t=>t.Password);

            if (GetAll().Any(t => t.UserName.ToLower().Trim() == model.UserName.ToLower().Trim()))
            {
                Guard.Throw("用户名已存在");
            }
            if (model.Password.Trim().Length<6)
            {
                Guard.Throw("密码至少6位");
            }
            model.Password = Hyt.Core.Cryptography.MD5.Encrypt(model.Password.Trim().ToLower()).ToLower();
            if (string.IsNullOrWhiteSpace(model.Name))
            {
                model.Name = model.UserName;
            }
            return Repository.AddAdministrator(model);
        }

        public virtual void Remove(Administrator model)
        {
            Repository.RemoveAdministrator(model);
        }

        public virtual void Lock(Guid id)
        {
            var model = Get(id);
            Guard.MustExist(model, "用户");
            if (model.State == PassportStatus.Disabled) return;
            model.State= PassportStatus.Disabled;
            Repository.UpdateAdministrator(model); 
        }

        public virtual void UnLock(Guid id)
        {
            var model = Get(id);
            Guard.MustExist(model, "用户");
            if (model.State == PassportStatus.Normal) return;
            model.State = PassportStatus.Normal;
            Repository.UpdateAdministrator(model);
        }

        public virtual IQueryable<Administrator> GetAll(QueryOption<Administrator> option = null)
        {
            return Repository.GetAdministrators(option);
        }

        public virtual Administrator Get(Guid id)
        {
            return Repository.GetAdministrators().FirstOrDefault(t => t.Id == id);
        }

        public virtual IPagedQueryable<Administrator> GetAdministrators(AdministratorQueryModel qo)
        {
            IPagedQueryable<Administrator> result = new PagedQueryable<Administrator>();
            var all = GetAll(qo.QueryOption.Cast<Administrator>());
            if (!string.IsNullOrWhiteSpace(qo.Name))
            {
                all = all.Where(t => t.Name.Contains(qo.Name));
            }
            if (qo.DepartMentId != null && qo.DepartMentId != Guid.Empty)
            {
                var alldepts = DepartmentService.GetSelfAndChild(qo.DepartMentId);
                all = all.Where(t => alldepts.Any(d => d.Id == t.DepartmentId));
            }
            if (qo.PositioinId != null && qo.PositioinId != Guid.Empty)
            {
                all = all.Where(t => t.PositionId == qo.PositioinId);
            }
            result.Total = all.Count();
            if (!string.IsNullOrWhiteSpace(qo.OrderBy))
            {
                all = all.SortBy(qo.OrderBy, qo.OrderType);
                all = all.PageBy(qo.PageIndex, qo.PageSize);
            }
            result.Data = all;
            result.PageIndex = qo.PageIndex;
            result.PageSize = qo.PageSize;
            return result;

        }

    }
}
